<template>
	<div>
		<canvas id="posterCanvas" canvas-id="posterCanvas" style="position: fixed; left: 100%"  ref="posterCanvas"
			:style="{ width: canvasStyle.width + 'px', height: canvasStyle.height + 'px' }"></canvas>
	</div>
</template>

<script>
/**
 *  isShow是否开始绘制
 *  canvasInfoArr:（Array） 画布绘制内容
 * 	  isBg:是否是背景图 - 根据背景图绘制画布宽高
 *	  type: 绘制类型
 * 		graphical矩形
 * 		img图片
 * 		text文字
 *   	uls渲染数组上下两行文字
 *    url:图片地址；text:绘制得文字内容
 *	  x:x轴坐标；y:y轴坐标
 * 	  w:宽度；h:高度；r:圆角弧度；fillStyle:形状填充色
 * 	  weight: 文字是否加粗 (bold,normal);size:字体大;color:文字颜色
 *    x_add:{} 在当前文字渲染完成后得位置继续渲染
 * 	  drawArticleWidth: 文字溢出换行得宽度
 *    listInfo: 渲染上下两行文字  {x:z坐标,w:宽度,topList:[{配置项同text配置,x是针对于listInfo得而言}]第一行显示文字  bottomList:[{配置项同text配置，x-y针对于toplist对应内容得x-y而言}]第二行显示文字} 数组长度一致
 *
 * */
export default {
	name: 'posterCanvas',
	props: {
		isShow: false,
		canvasInfoArr: {
			default: () => []
		},
		isUplode: true,
		imgFile: {
			default: null
		}
	},
	watch: {
		isShow(curr) {
			if (curr) {
				this.ctx = uni.createCanvasContext('posterCanvas', this);
				setTimeout(() => {
					this.getPosterImg();
				}, 300);
			}else{
				this.ctx= null
				this.canvasStyle= {
					width: 340, // 画布宽度  固定画布宽度 设计稿宽度为340
					height: 0 // 画布高度
				}
			}
		}
	},
	data() {
		return {
			ctx: null,
			canvasStyle: {
				width: 340, // 画布宽度  固定画布宽度 设计稿宽度为340
				height: 0 // 画布高度
			}
		};
	},
	methods: {
		// 绘制海报
		async getPosterImg() {
			let that = this;
			// https://bicpic.baikewang.com/word_poster/template/1.jpg   随机生成1-50数字
			const ctx = that.ctx;
			let systemInfo = await uni.getSystemInfoSync();
			// 缩放物理像素比
			let ratio = systemInfo.devicePixelRatio || 1; // 清晰显示画布比例
			if (!that.canvasInfoArr.length) {
				uni.showToast({
					icon: 'none',
					mask: true,
					title: '数据获取失败'
				});
				uni.hideLoading();
				return;
			}
			let bgImgInfo = that.canvasInfoArr.filter((item) => item.isBg) || [];
			if (bgImgInfo.length) {
				let info = bgImgInfo[0];
				let canvasW = info.w; // 画布宽度  固定画布宽度 设计稿宽度为340
				let canvasH = info.h; // 画布高度 = 主图高度+二维码高度 + 间距（大概50）
				if (canvasH * ratio > 4000) {
					that.canvasStyle.width = canvasW;
					that.canvasStyle.height = canvasH;
				} else {
					that.canvasStyle.width = canvasW * ratio;
					that.canvasStyle.height = canvasH * ratio;
					ctx.scale(ratio, ratio); // 缩放画布
				}
			}
			let obj = {
				graphical: 'drawRadius',
				text: 'drawFont',
				img: 'drawImg',
				uls: 'drawArr'
			};
			for (let i = 0; i < that.canvasInfoArr.length; i++) {
				let info = that.canvasInfoArr[i];
				if (that[obj[info.type]]) {
					await that[obj[info.type]](ctx, info);
				}
			}
			setTimeout(() => {
				ctx.draw(true,setTimeout(() => {
					uni.canvasToTempFilePath(
						{
							canvasId: 'posterCanvas',
							quality: 0.5,
							x: 0,
							y: 0,
							fileType: 'jpg',
							success: (res) => {
								// #ifdef MP||APP-PLUS
								uni.compressImage({
									src: res.tempFilePath,
									quality: 40,
									complete: (res2) => {
										if (that.isUplode) {
											that.uploadImg(res2.tempFilePath);
										} else {
											that.$emit('posterImg', { url: res2.tempFilePath, cavasImg: res2.tempFilePath });
										}
									}
								});
								// #endif
								// #ifdef H5
								if (that.isUplode) {
									that.uploadImg(res.tempFilePath);
								} else {
									that.$emit('posterImg', { url: res.tempFilePath, cavasImg: res.tempFilePath });
								}
								// #endif
							}
						},that
					);
				}, 300));
			}, 300);
		},
		// 绘制矩形 可圆角
		drawRadius(ctx, tipsInfo) {
			let that = this;
			let { x = 0, y = 0, w = 0, h = 0, r = 0, strokeStyle = 'transparent', linearInfo, fillStyle = 'transparent', lineWidth = 0 } = tipsInfo;
			ctx.beginPath();
			// 纵向渐变
			if (linearInfo) {
				let myliGra = null;
				let methods = 'to bottom';
				methods = linearInfo.methods || methods;
				if (methods == 'to bottom') {
					myliGra = ctx.createLinearGradient(x, y, 0, y + h);
				} else {
					myliGra = ctx.createLinearGradient(x, y, x + w, 0);
				}
				// myliGra.addColorStop(0, 'rgba(255,255,255,.2)');
				// myliGra.addColorStop(1, 'rgba(255,255,255,.9)');
				linearInfo.addColor.forEach((item) => {
					myliGra.addColorStop(item.val, item.color);
				});
				// ctx.setFillStyle(myliGra);
				//将该渐变设置为填充样式
				ctx.fillStyle = myliGra;
				ctx.fillRect(x, y, w, h);
			} else {
				ctx.fillStyle = fillStyle;
			}
			ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5);
			ctx.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2);
			ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5);
			ctx.arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI);
			// 结束绘制路径
			ctx.closePath();
			ctx.strokeStyle = strokeStyle;
			ctx.stroke();
			// ctx.lineWidth = lineWidth;
			// 对绘画区域填充
			ctx.fill();
		},
		// 绘制图片
		async drawImg(ctx, info) {
			let that = this;
			let { w = 0, h = 0, x = 0, y = 0, r = 0, url = '', isBase64 = false } = info;
			if (!url) return;
			let imgInfo = {};
			if (!isBase64) {
				imgInfo = await that.getImageInfo(url);
				if (!h) {
					h = w * (imgInfo.height / imgInfo.width);
				}
				if (!w) {
					w = h * (imgInfo.width / imgInfo.height);
				}
			}
			if (r) {
				ctx.save();
				ctx.strokeStyle = 'transparent';
				ctx.stroke();
				that.drawRadius(
					ctx,
					Object.assign({}, info, {
						strokeStyle: 'transparent'
					})
				);
				ctx.clip();

				ctx.drawImage(!isBase64 ? imgInfo.path : url, x, y, w, h);
				ctx.restore();
			} else {
				ctx.drawImage(!isBase64 ? imgInfo.path : url, x, y, w, h);
			}
		},
		// 绘制文字
		async drawFont(ctx, info) {
			let that = this;
			let { text = '', weight = 'normal', size = 0, color = '#121317', base = 'left', x = 0, y = 0, x_add = {}, drawArticleWidth = 0, maxRow = 2 } = info;
			text = text + '';
			ctx.font = `normal ${weight} ${size}px 'myFamily'`;
			ctx.setTextAlign(base);
			ctx.setFillStyle(color || '#121317');
			ctx.setFontSize(size || 14);
			if (drawArticleWidth) {
				that.drawArticle(ctx, text, drawArticleWidth, x, y, maxRow);
				return;
			}
			ctx.fillText(text, x, y);

			if (x_add.text) {
				let _width = that.getMeasureTextWidth(ctx, text);
				x += _width;
				let newInfo = Object.assign({}, info, x_add, {
					x_add: x_add.x_add || {},
					x: x
				});
				await that.drawFont(ctx, newInfo);
			}
		},
		// 绘制统计区域
		async drawArr(ctx, info) {
			let that = this;
			let { x = 30, y = 0, w = 0, listInfo = {} } = info;
			let { topList = [], bottomList = [] } = listInfo;
			if (!topList.length) return;
			let liInfo = {
				w: w / topList.length,
				y: y
			};
			for (let i = 0; i < topList.length; i++) {
				let topItem = topList[i];
				topItem.x += x + liInfo.w * i;
				await that.drawFont(ctx, topItem);

				let bottomItem = bottomList[i];
				bottomItem.x += x + liInfo.w * i + 2;
				bottomItem.y += topItem.y;
				await that.drawFont(ctx, bottomItem);
			}
		},
		// 获取文本宽度
		getMeasureTextWidth(ctx, text) {
			let min_width = Math.ceil(text.length * 13);
			let _width = Math.ceil(ctx.measureText(text).width);
			// let _width_little = text.length >= 8 ? Math.ceil(ctx.measureText('我').width) : 0;
			return _width < min_width && text.length >= 8 ? min_width : _width;
		},
		// 文本宽度计算
		drawArticle(ctx, text, width, x, y, maxRow = 2) {
			let chr = text.split(''); // 分割为字符串数组
			let temp = '';
			let row = [];
			for (let a = 0; a < chr.length; a++) {
				if (ctx.measureText(temp).width < width) {
					temp += chr[a];
				} else {
					a--;
					row.push(temp);
					temp = '';
				}
			}
			row.push(temp);
			for (let b = 0; b < row.length; b++) {
				// 控制最多显示2行
				if (b < maxRow) {
					if (b === 1) {
						if (row.length > maxRow) {
							row[b] = row[b].substring('', row[b].length - 1);
							row[b] = row[b] + '...';
						}
					}
					ctx.fillText(row[b], x, y + b * (13 + 3));
				}
			}

			let _len = row.length > maxRow ? maxRow : row.length;
			// return y + (_len - 1) * 20
			return _len;
		},
		// 获取图片信息
		getImageInfo(image) {
			return new Promise((req, rej) => {
				uni.getImageInfo({
					src: image,
					success: function (res) {
						req(res);
					},
					fail: function (fail) {
						// console.log(fail, '************************');
					}
				});
			});
		},
		// 获取文件详情
		getFileInfo(url) {
			return new Promise((req, rej) => {
				uni.getFileInfo({
					filePath: url,
					success: function (res) {
						req(res);
					}
				});
			});
		},

		// 获取设备信息
		getSystemInfo() {
			return new Promise((req, rej) => {
				uni.getSystemInfo({
					success: function (res) {
						req(res);
					}
				});
			});
		},
		// 上传图片
		async uploadImg(posterUrl) {
			let that = this;
			let { code, data } = await that.$application_api.getOssToken();
			if (code != 0) return;
			let suffix = posterUrl.split('.')[1] || 'png';
			let path = data.url;
			let randomStr = that.randomString(6);
			let _date = that.$moment().format(`YYYY/MM/DD`);
			let file_name = `/baike_app/${that.imgFile || 'singup_poster'}/${_date}/` + new Date().getTime() + '-' + randomStr + '.' + suffix;
			let obj = Object.assign({}, data, {
				key: file_name,
				success_action_status: '200'
			});
			uni.uploadFile({
				url: data.url,
				filePath: posterUrl,
				name: 'file',
				formData: obj,
				success: (res) => {
					if (res.statusCode === 200) {
						that.$emit('posterImg', { url: `${path}${file_name}`, cavasImg: posterUrl });
						uni.hideLoading();
						uni.showToast({
							icon: 'none',
							mask: true,
							title: '绘制完成'
						});
					} else {
						uni.showToast({
							icon: 'none',
							title: '上传失败'
						});
					}
				},
				fail: function (err) {
					uni.showToast({
						icon: 'none',
						title: '上传失败'
					});
				}
			});
		}
	},
	created() {
		/* 在线链接服务仅供平台体验和调试使用，平台不承诺服务的稳定性，企业客户需下载字体包自行发布使用并做好备份。 */
		// @font-face {
		//   font-family: "思源黑体 Normal";font-weight: 350;src: url("//at.alicdn.com/wf/webfont/9HfHf1MBhwSN/RN1qwepz5xtk.woff2") format("woff2"),
		//   url("//at.alicdn.com/wf/webfont/9HfHf1MBhwSN/OkRzAMkCKVIb.woff") format("woff");
		//   font-display: swap;
		// }
		// wx.loadFontFace({
		// 	global: true,
		// 	family: 'myFamily',
		// 	source: 'url("https://at.alicdn.com/wf/webfont/9HfHf1MBhwSN/OkRzAMkCKVIb.woff")',
		// 	scopes: ['webview', 'native'],
		// 	success: function (res) {
		// 		// console.log('字体加载完成', res);
		// 	},
		// 	fail: function (res) {
		// 		// console.log('字体加载失败');
		// 	},
		// 	complete: function (res) {
		// 		// console.log(res.status);
		// 	}
		// });
	}
};
</script>

<style lang="less" scoped></style>
